#ifndef TREECOMBOBOX_H
#define TREECOMBOBOX_H

/*	--howto--

	TreeComboBox combo;
	QStandardItemModel model;
	model.appendRow(new QStandardItem("Test1"));
	model.item(0)->appendRow(new QStandardItem("Test1.1"));
	model.item(0)->appendRow(new QStandardItem("Test1.2"));
	model.item(0)->appendRow(new QStandardItem("Test1.3"));
	combo.setModel(&model);
	combo.show();
*/

#include <QtGui>

class TreeComboBoxView : public QTreeView
{
public:
	TreeComboBoxView(QWidget* parent = 0) : QTreeView(parent)
	{
		header()->hide();
	}

	QRect visualRect (const QModelIndex & index) const
	{
		QRect rect = QTreeView::visualRect(index);
		if (!index.isValid()) return rect;
		int rows = index.model()->rowCount();
		if (!index.parent().isValid() && index.row() == rows-1) {
			int minHeight = 150;
			int height = rect.height() * rows;
			if (height < minHeight) {
				rect.setHeight(rect.height() + minHeight-height);
			}
		}
		return rect;
	}
};

class TreeComboBox : public QComboBox
{
public:
	TreeComboBox(QWidget* parent = 0) : QComboBox(parent), skipNextHide(false)
	{
		setView(new TreeComboBoxView(this));
		view()->viewport()->installEventFilter(this);
	}

	bool eventFilter(QObject* object, QEvent* event)
	{
		if (event->type() == QEvent::MouseButtonPress && object == view()->viewport())
		{
			QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
			QModelIndex index = view()->indexAt(mouseEvent->pos());
			if (!view()->visualRect(index).contains(mouseEvent->pos()))
				skipNextHide = true;
		}
		return false;
	}

	virtual void showPopup()
	{
		setRootModelIndex(QModelIndex());
		QComboBox::showPopup();
	}

	virtual void hidePopup()
	{
		setRootModelIndex(view()->currentIndex().parent());
		setCurrentIndex(view()->currentIndex().row());
		if (skipNextHide)
			skipNextHide = false;
		else
			QComboBox::hidePopup();
	}

private:
	bool skipNextHide;
};

#endif // TREECOMBOBOX_H
